ci: add import profiler check across monorepo#17657
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds a new import_profile session to the noxfile.py.j2 template to measure and ensure import times remain below defined thresholds. Feedback points out that because this template is used in standalone repositories outside of the monorepo, referencing a relative path to the monorepo's root scripts directory will cause default nox runs to fail in those environments. It is recommended to check for the script's existence and gracefully skip the session if it is missing, while also using pathlib.Path for cleaner path handling.
There was a problem hiding this comment.
I left a couple comments. It would be good to clarify the goal of this check though.
What counts as a failure? Can we calculate an import time diff before and after the target changes, instead of just reporting an absolute value? How are developers intended to interact with this?
| ;; | ||
| *) | ||
| nox -s ${TEST_TYPE} | ||
| retval=$? |
There was a problem hiding this comment.
This PR doesn't touch any packages, so it's hard to tell what the action will look like. Can you temporarily touch some files to test it out?
There was a problem hiding this comment.
We should also see how long the new check would take if all packages were updated. In #17438, I added a new unit_test:all_packages tag, that will run against all packages when added. Maybe we should support that here too
It's possible we would only want to profile a few key packages instead of all of them. Most generated libraries should be very similar
There was a problem hiding this comment.
I agree with Daniel on a couple of performance issues:
- I would like to see this thing run so that I can understand what it will produce and whether output appears as I would expect. Please temporarily touch some files to trigger the profiler to run against them. As an example: add a blank line right after the license in this file in google-cloud-compute and a similar change in at least one other package. That will trigger the profiler to run (without requiring you to go back and undo any changes to
google-cloud-compute, etc).
- If you already did this and have reverted your change, please point to the commit that you used to trigger the profiler (we should be able to check the CI/CD results for that commit).
Note
In case you've never done it... clicking on the x OR checkmark next to the commit number grants access to the test results for previous commits:
- If, as Daniel suggests, we run the profiler against all packages, it would be useful to know how long that CI/CD check will take. We have 240 generated packages and if we regen and profile all of them we don't wanna find out later that it takes hours. Do we have benchmark results to give us an order of magnitude for how long it takes?
There was a problem hiding this comment.
I've added a temporary commit (8a2d75b) that adds a blank line to google-cloud-compute and google-api-core so you can see the profiler run on a couple of real packages and review the output.
Regarding the benchmark on all packages, we actually already support running the profiler against all packages in this PR! Similar to how the unit_test:all_packages label works, there's logic in .github/workflows/import-profiler.yml that checks for an import_profile:all_packages label.
If we want to see how long it takes across all ~240 packages to get an order of magnitude, we can simply apply the import_profile:all_packages label to this PR and let it run.
113b3d5 to
9472ab6
Compare
|
/gemini |
| python -m pip install --upgrade setuptools pip wheel | ||
| python -m pip install nox |
There was a problem hiding this comment.
I might be missing it, if so, sorry. I don't see any specific references to your import profiler job using nox. We install it here, but when I check for the import_profile) case statement in run_single_test.sh` I don't see any nox references. Every other case explicitly uses nox to run their tests.
Note
Since you do not launch your script using a function from the noxfile.py, you should NOT need to install nox.
|
I reviewed the results of the profiler run. It appears as though it is partially successful and yet, halfway through each run for google-cloud-compute and google-api-core an error message appears Later in the same stretch we see some results that indicate a failure but do so in a way that is non-intuitive: If the built in profiler injects that line in its results, there may be nothing we can do about it, none-the-less, what we want to happen is for our process in its entirety to complete with either a success flag OR fail flag and have a message at the end. Something like this at the end of your profiler script could do the trick of signaling to the CI/CD workflow that the script resulted in a success OR failure result: |

Overview
This PR integrates the import profiler script (introduced in #17467) into our automated CI pipeline.
Why this matters: Import times significantly impact CLI responsiveness and cold starts for Serverless products like Cloud Run and Cloud Functions. Ideally, library imports should stay under 500ms, and anything taking over 1 second is a target for optimization. This CI check helps us proactively track metrics like import latency, memory footprint, and code volume to prevent performance regressions on critical libraries.
The primary goal of this check is to track and enforce performance standards for package import times across the repository, especially following our recent work on lazy loading and cold-start optimizations.
By running this benchmark as a CI check with a defined dynamic differential failure threshold, we can programmatically prevent latency regressions in module initialization times before they are merged, ensuring downstream consumers aren't impacted by unexpectedly slow startup times.
Changes Included
.github/workflows/import-profiler.yml) that triggers on PRs and merge groups. The workflow is pinned specifically to Python 3.15.noxfile.py.j2) and forcing updates across 150+ packages, the CI script (ci/run_single_test.sh) natively handles the profiler. It automatically spins up a lightweight virtual environment, installs the target package, and runs the profiler.ci/run_single_test.shto checkoutHEAD^1(the main branch), generate a baseline CSV profile, and then diff it against the PR branch. If the P99 import time of the PR degrades by >100ms compared to the baseline, the CI check will fail.setup.pyexists before attempting to profile, gracefully skipping directories that are not valid Python packages.import_profile:all_packageslabel to a Pull Request will force the CI pipeline to run the profiler check against all packages in the mono-repo, instead of just the modified ones.Developer Interactions
If a developer fails this CI check due to an import latency regression, they can reproduce and debug it locally by running the profiler script with the
--cprofileflag (python scripts/import_profiler/profiler.py --package <their-package> --cprofile). This will generate a cProfile stack trace breakdown of the import time, allowing them to pinpoint exactly which new dependency or module initialization is causing the latency spike.Related PRs
Builds upon the import profiler tool added in #17467